/**
 * Description:
 * Class Name:subject2_use_synchronized_block
 * Date:2022/5/20 9:55
 *
 * @author LTisme
 * @version JAVA17
 */
package 疯狂Java讲义.第16章_多线程.课后练习;

class Garage{
    public static boolean[] parkPlace = {true, true, true};
}

class Vehicle extends Thread{
    private int parkedPoint = -1;
    private boolean isParked = false;

    public Vehicle(String name){
        super(name);
    }

    public int getPositionIfExists(){
        for (int i = 0; i < Garage.parkPlace.length; i++) {
            if (Garage.parkPlace[i]){
                return i;
            }
        }
        return -1;
    }

    public void park(){
        synchronized (Garage.class){
            try {
                while (getPositionIfExists() == -1){
                    System.out.println(Thread.currentThread().getName() + " 号车因停车场已满无法停车。");
                    Garage.class.wait();
                }
                parkedPoint = getPositionIfExists();
                Garage.parkPlace[parkedPoint ] = false;
                isParked = true;
                System.out.println(Thread.currentThread().getName() + " 号车在 " + parkedPoint + " 位置停车成功。");
                Garage.class.notifyAll();
            }
            catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    public void leave(){
        synchronized (Garage.class){
            try {
                while (!isParked){
                    System.out.println(Thread.currentThread().getName() + " 号车因为尚未停车无法离开");
                    Garage.class.wait();
                }
                Garage.parkPlace[parkedPoint ] = true;
                System.out.println(Thread.currentThread().getName() + " 号车已离开 " + parkedPoint + " 车位。");
                parkedPoint = -1;
                Garage.class.notifyAll();
            }
            catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public void run() {
        try {
            park();
            Thread.sleep(200);
            leave();
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
}

public class subject2_use_synchronized_block {
    public static void main(String[] args) {
        new Vehicle("c1").start();
        new Vehicle("c2").start();
        new Vehicle("c3").start();
        new Vehicle("c4").start();
        new Vehicle("c5").start();
        new Vehicle("c6").start();
    }
}
